package com.lzs.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.lzs.common.thread.ThreadLocalUtil;
import com.lzs.common.utils.MyHttpUtils;
import com.lzs.common.vo.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * FileName: CommonInterceptor
 * <p>
 * Description: 自定义拦截器
 *
 * @author lzs
 * @version 1.0.0
 * @create 2019/3/22 17:16
 */
@Slf4j
public class CommonInterceptor extends HandlerInterceptorAdapter {

    private static final String start = "========request start======";

    private static final String end   = "========request end=========";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        MDC.put("TRACE_ID", Long.toString(com.xiaomojiang.common.model.traceid.TraceIDUtil.incrementAndGet()));
        log.info(start);
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Runtime runtime = Runtime.getRuntime();
            Class<?> aClass = handlerMethod.getBean().getClass();
            Method method = handlerMethod.getMethod();
            log.info("现在开始运行这个类[{}]的这个方法[{}]",aClass.getName(), method.getName());
            if (
                    request.getMethod().equals(HttpMethod.POST.toString())
                    || request.getMethod().equals(HttpMethod.PUT.toString())
            ) {
                //上传文件请求
                if (StringUtils.indexOf(request.getContentType(),"multipart/form-data")==0) {
                    log.info("上传文件请求，跳过参数打印");
                }else {
                    String postData = MyHttpUtils.getPostData(request);
                    log.info("body参数=[{}]",postData);
                }
            }else {
                Map<String, String[]> parameterMap = request.getParameterMap();
                log.info("路径参数=[{}]",JSON.toJSONString(parameterMap));
            }
            log.info("剩余的JVM剩余内存是[{}]mb",runtime.freeMemory()/1024/1024);
//            log.info("JVM总内存是mb",runtime.maxMemory()/1024/1024);
//            log.info("JVM挖到了{}mb",runtime.totalMemory()/1024/1024);
//            log.info("JVM可以用{}个cpu",runtime.availableProcessors());
        }
        //记录一下执行时间
        String nowTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //获取到执行的路径
        String url = request.getRequestURI();
        log.info("[{}]: 进入的时间:[{}]",url,nowTimeStr);
        //将当前的毫秒值放到request中就行了
        request.setAttribute("START_TIME",System.currentTimeMillis());
        return true;
    }



    private void builderErrorResponse(HttpServletResponse response, String describe) throws IOException {
        CommonResult commonResult = CommonResult.Err("该用户无法访问[" + describe + "]接口");
        commonResult.setCode(403);
        response.addHeader("Accept", "application/json");
        response.addHeader("Content-type", "application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(commonResult));
        writer.close();
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //和afterCompletion差不多 这个出现异常的话不执行
        //在这里将线程中的东西移除
        ThreadLocalUtil.removeBatch();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Runtime runtime = Runtime.getRuntime();
            log.info("现在结束运行这个类[{}]的这个方法[{}]",handlerMethod.getBean().getClass().getName(),handlerMethod.getMethod().getName());
            log.info("剩余的JVM剩余内存是[{}]mb",runtime.freeMemory()/1024/1024);
//            log.info("JVM总内存是{}mb",runtime.maxMemory()/1024/1024);
//            log.info("JVM挖到了{}mb",runtime.totalMemory()/1024/1024);
//            log.info("JVM可以用{}个cpu",runtime.availableProcessors());
        }
        //从request中获得到执行的时间
        Long startTime = (Long) request.getAttribute("START_TIME");
        Long endTime = System.currentTimeMillis();
        log.info("total time:[{}]ms",(endTime-startTime));
        request.removeAttribute("START_TIME");

        log.info(end);
        //在这里页进行移除
        ThreadLocalUtil.removeBatch();
    }
}
